/*
 * @Author: Suo-Yuheng syh15399227325@163.com
 * @Date: 2025-08-22 23:05:45
 * @LastEditors: Suo-Yuheng syh15399227325@163.com
 * @LastEditTime: 2025-08-24 14:39:29
 * @FilePath: /0822/pipe/pipe.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AEi
 */
#include<iostream>
#include<unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include<cstring>

using namespace std;

void Writer(int wfd)
{
    string s = "hello i am a child";
    pid_t self = getpid();
    int number = 0;

    char buffer[1024];
    while(true)
    {
        sleep(1);
        // 构建发送字符串
        buffer[0] = 0; // 字符串清空，只是为了提醒，这个数组是个 字符串
        snprintf(buffer, sizeof(buffer), "%s-%d-%d", s.c_str(), self, number++);
        // cout << buffer << endl;
        // 发送/写入 给父进程
        write(wfd, buffer, strlen(buffer)); // 字符串不用写 \0
        
        
        // sleep(1);
        // char c = 'c';
        // write(wfd, &c, 1);
        // number++;
        // cout << number << endl;

        // if(number >= 5) break;
    }
}

void Reader(int rfd)
{
    char buffer[1024];
    int cnt = 5;

    while(cnt--)
    {
        buffer[0] = 0;
        ssize_t n =read(rfd, buffer, sizeof(buffer));
        if(n > 0)
        {
            buffer[n] = 0;  // 当字符串用
            cout << "father get a message[" << getpid() << "]#" << buffer << endl;
        }
        
        // sleep(1);
    }
}

int main()
{
    int pipefd[2] = {0};
    int n = pipe(pipefd);      // 父进程 创建 管道
    if(n < 0) return 1;
    // cout << "pipefd[0]" << pipefd[0] << endl;
    // cout << "pipefd[1]" << pipefd[1] << endl;

    pid_t id = fork();  // 创建子进程，此时已经父子进程已经对 管道建立了 读、取的 文件对象、描述符
    if(id < 0)  return 2;
    if(id == 0)
    {
        // child- >  write
        close(pipefd[0]);   // 建立了单向信道
        Writer(pipefd[1]);

        close(pipefd[1]);
        exit(0);
    }
    // father - > read
    close(pipefd[1]);
    Reader(pipefd[0]);
    close(pipefd[0]);
    cout << "father close read fd:" << pipefd[0] << endl;
    sleep(5);   // 观察僵尸

    int status = 0;
    pid_t rid = waitpid(id, &status, 0);
    if(rid < 0) return 3;
    
    cout << "wait child success: " << rid << " exit code: " << ((status>>8) & 0xFF) << "exit signal: " << (status & 0x7F) << endl;
    sleep(5);

    cout << "father exit" << endl;

    return 0;
}